


package scene
{
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.text.TextField;
	import flash.ui.Keyboard;
	import flash.utils.ByteArray;
	import flash.utils.IDataInput;
	
	import interfaces.IDispose;
	import mapbase.bigTile;
	import mapbase.map;
	import mapbase.mapScene;
	import mapbase.mapTerrain;
	import resources.ImageResource;
	import resources.SceneImageResProvider;
	import utils.GameState;
	import utils.HashMap;
	
	public class gameScene extends Sprite  implements IDispose
	{		
		private var _mapSceneOffSet:Point = new Point(200,300);				//屏幕原点在整张地图中的位置
		private var _viewPort:Point = new Point(1000,600);			//视口大小
		private var _screenDrawGrids:Rectangle = new Rectangle();		//屏幕渲染区	 格子位置
		private var _screenDrawPixel:Rectangle = new Rectangle();		//屏幕渲染区	像素位置
		private var _9Screen:Vector.<Point>;		//9屏信息
		
		private var _mapScene:mapScene = new mapScene();				//地图资源
		
		private var bigTerrain:Sprite = new Sprite();				//大地表		渲染
		
		private var bigTerrainInfo:HashMap = new HashMap();			//key index 		value bigtile
		
		private var _reDraw:Boolean = true;
		private var _ResLoadOk:Boolean = false;
		
		private var _drawFPS:TextField = new TextField();
		
		public function gameScene():void
		{			
			_9Screen = new Vector.<Point>();
			_9Screen.push(new Point(0,0),new Point(0,0),new Point(0,0),
							new Point(0,0),new Point(0,0),new Point(0,0),
							new Point(0,0),new Point(0,0),new Point(0,0));
			super();			
			
			this.addEventListener(Event.ENTER_FRAME,freshFrame);
			this.addEventListener(Event.ADDED_TO_STAGE,add_to_stage);
			this.addEventListener(KeyboardEvent.KEY_UP,handleKeyboard);		
			this.addEventListener(Event.RESIZE,resize)
		}
		
		public function add_to_stage(e:Event):void
		{
			this.stage.addChild(bigTerrain);	
			this.stage.addEventListener(MouseEvent.MOUSE_UP,mouseHandle);
			
			this.stage.addChild(_drawFPS);
			_drawFPS.x = 20;
			_drawFPS.y = 20;
			_drawFPS.textColor = 0xff0000;
			
			SceneImageResProvider.instance.startPreLoad(null,resLoadOK);
		}
		
		public function resize(e:Event):void
		{
			this.preRender();
		}
		
		public function resLoadOK():void
		{
			_ResLoadOk = true;
		}
		
		public function load(filename:String):void
		{					
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.BINARY;
			loader.addEventListener(Event.COMPLETE, onDownloadComplete);
//			loader.addEventListener(IOErrorEvent.IO_ERROR, onDownloadError);
//			loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onDownloadSecurityError);
			
			var request:URLRequest = new URLRequest();
			request.url = filename;
			loader.load(request);
			
			// Keep reference so the URLLoader isn't GC'ed.
//			_urlLoader = loader;
		}
		
		private function onDownloadComplete(event:Event):void
		{
			var data:ByteArray = ((event.target) as URLLoader).data as ByteArray;
			
			loadScene(data);			
			
			(event.target as URLLoader).removeEventListener(Event.COMPLETE,onDownloadComplete);					
		}
		
		public function loadImge(i:int):void
		{	
			var b:Boolean = SceneImageResProvider.instance.getRes(i) != null;
			if(!b)
			{
				var url:String = "config/map/" + mapTerrain.getGroup(i) + "_" + mapTerrain.getFrame(i) + ".jpg";
				
				SceneImageResProvider.instance.addImage(url,i);	
				
				_ResLoadOk = false;
			}					
		}		
		
		public function loadScene(data:IDataInput):Boolean
		{
			_mapScene.loadMap(data);
			
			preRender();
			
			return true;
		}
		
		public function set viewPort(pt:Point):void
		{
			_viewPort = pt;			
		}
		public function get viewPort():Point
		{
			return _viewPort;
		}
		
		public function updateDrawInfo():void
		{
			_viewPort.x = stage.stageWidth;
			_viewPort.y = stage.stageHeight;
			
			_screenDrawPixel.left = _mapSceneOffSet.x;
			_screenDrawPixel.top = _mapSceneOffSet.y;
			if(_screenDrawPixel.left < 0)
			{
				_screenDrawPixel.left = 0;
			}
			if(_screenDrawPixel.top < 0)
			{
				_screenDrawPixel.top = 0;
			}
			
			_screenDrawPixel.right = _screenDrawPixel.left + _viewPort.x;
			_screenDrawPixel.bottom = _screenDrawPixel.top + _viewPort.y;			
			
			if(_screenDrawPixel.right > _mapScene.width() * map.gridWidth)
			{				
				_screenDrawPixel.right = _mapScene.width() * map.gridWidth;
				_screenDrawPixel.left = _screenDrawPixel.right - viewPort.x;
			}
			if(_screenDrawPixel.bottom > _mapScene.height() * map.gridHeight)
			{
				_screenDrawPixel.bottom = _mapScene.height() * map.gridHeight;
				_screenDrawPixel.top = _screenDrawPixel.bottom - viewPort.y;
			}						
			
			_mapSceneOffSet.x = _screenDrawPixel.left;
			_mapSceneOffSet.y = _screenDrawPixel.top;
			
			_screenDrawGrids = map.map_PixelToGrid_Rc(_screenDrawPixel);
		}
		
		//		0	1	2
		//		3	4	5
		//		6	7	8
		
		public function update9Screen():void
		{
			_9Screen[0] = map.map_GirdToScreen(_screenDrawGrids.topLeft);
			
			for(var k:int = 0; k != 9; ++k)
			{
				_9Screen[k].x = _9Screen[0].x + (k % 3);
				_9Screen[k].y = _9Screen[0].y + int(k / 3);
			}
		}
		
		public function loadTerrainRes():void
		{
			var startgrid:Point = map.map_ScreenToGrid(_9Screen[0]);			
			
			for(var h:int = 0; h != map.screen9_Terrains_H; ++h)
			{
				for(var w:int = 0; w != map.screen9_Terrains_W; ++w)
				{
					var t:mapTerrain = _mapScene.Map.getTerrain(startgrid.x + w * mapTerrain.one_Grids_W,
												startgrid.y + h * mapTerrain.one_Grids_H);
					if(t)
					{
						var idx:int = t.bmp;
						
//						trace(startgrid.x + w * mapTerrain.one_Grids_W,startgrid.y + h * mapTerrain.one_Grids_H);
						
						if(idx != -1)
						{
							loadImge(idx);
						}
					}					
				}
			}
			
			SceneImageResProvider.instance.startLoad();
		}
		
		public function renderTerrain():void
		{
			var _t:Rectangle = new Rectangle();
			_t.topLeft = map.map_GridToTerrain(_screenDrawGrids.topLeft);
			_t.right = int((_screenDrawGrids.right + mapTerrain.one_Grids_W - 1) / mapTerrain.one_Grids_W);
			_t.bottom = int((_screenDrawGrids.bottom + mapTerrain.one_Grids_H - 1) / mapTerrain.one_Grids_H);			
			
			for(var h:int = _t.top; h != _t.bottom; ++h)
			{
				for(var w:int = _t.left; w != _t.right; ++w)
				{
					var ID:int = mapTerrain.createID(h,w);						
					 						
					var _x:int = map.gridWidth * mapTerrain.one_Grids_W * w;
					var _y:int = map.gridHeight * mapTerrain.one_Grids_H * h;
					var drawPixel:Rectangle = new Rectangle(_x,_y,
														mapTerrain.one_Grids_W * map.gridWidth,
														mapTerrain.one_Grids_H * map.gridHeight);
					if(_screenDrawPixel.intersection(drawPixel).isEmpty())
					{
						continue;
					}					
					
					var terrain:bigTile;
					//缓存
					if(bigTerrainInfo.containsKey(ID))
					{
						terrain = bigTerrainInfo.get(ID) as bigTile;																					
					}
					else
					{
						var res:ImageResource = SceneImageResProvider.instance.getRes(ID);
						if(res)
						{
							terrain = new bigTile();
							terrain.bitmap = res.image;							
							
							bigTerrainInfo.put(ID,terrain);
							bigTerrain.addChild(terrain.bitmap);
						}						
					}
					
					if(terrain)
					{
						terrain.bitmap.visible = true;	
						terrain.removed = false;
						terrain.drawPixelRect = drawPixel;
						terrain.bitmap.x = drawPixel.x - _mapSceneOffSet.x;
						terrain.bitmap.y = drawPixel.y - _mapSceneOffSet.y;
						
//						trace(terrain.bitmap.x,terrain.bitmap.y);
					}					
				}
			}			
		}
		
		public function mouseHandle(e:MouseEvent):void
		{
			var _x:int = int(e.stageX - this.stage.stageWidth / 2);
			var _y:int = int(e.stageY - this.stage.stageHeight * 2 / 3);
			
			_mapSceneOffSet.x += _x;
			_mapSceneOffSet.y += _y;
			
			preRender();
		}
		
		public function freshFrame(e:Event):void
		{
			if(!_reDraw || !_ResLoadOk)
			{
//				return ;
			}
			
			clipping();
			
			renderTerrain();
			
			_reDraw = false;
			
			GameState.instance.freshFrame();
			
			_drawFPS.text = "curFPS " + GameState.instance.fps
		}
		
		public function clipping():void
		{
			for each(var v:* in bigTerrainInfo.values())
			{
				var bigtile:bigTile = v as bigTile;
				if(_screenDrawPixel.intersection(bigtile.drawPixelRect).isEmpty() && !bigtile.removed)
				{
					bigtile.removed = true;
					bigtile.bitmap.visible = false;
				}
			}
		}
		
		public function handleKeyboard(e:KeyboardEvent):void
		{
			switch(e.keyCode)
			{
				case Keyboard.UP:
				{
					_mapSceneOffSet.y -= 1000;
				}
				break;
				case Keyboard.DOWN:
				{
					_mapSceneOffSet.y += 1000;
				}
				break;
				case Keyboard.LEFT:
				{
					_mapSceneOffSet.x -= 1000;
				}
				break;
				case Keyboard.RIGHT:
				{
					_mapSceneOffSet.x += 1000;
				}
				break;
			}
			
			preRender();
		}
		
		public function preRender():void
		{
			updateDrawInfo();
			
			update9Screen();
			
			loadTerrainRes();						
			
			_reDraw = true;
		}
		
		public function dispose():void
		{
			for(var i:int = 0; i != 9; ++i)
			{
				delete _9Screen[i];
			}
		}
	}
}